<script setup name="VxeTableCommon">
import XEClipboard from "xe-clipboard";
import VXETable from "vxe-table";
import {getsaveTableColumn} from '@/api/Mine/tableColumnStyle'
import useUserStore from "@/store/modules/user.js";
import {computed, getCurrentInstance, onMounted, reactive, ref, toRefs, watchEffect} from "vue";

const props = defineProps({
  checkbox: {
    type: Boolean,
    default: false
  },
  radio: {
    type: Boolean,
    default: false
  },
  seq: {
    type: Boolean,
    default: false
  },
  tableData: {
    type: Array,
    default: () => []
  },
  tableColumn: {
    type: Array,
    default: () => []
  },
  loading: {
    type: Boolean,
    default: false,
  },
  isPage: {
    type: Boolean,
    default: false,
  },
  total: {
    type: Number,
    default: 0,
  },
  // 当前页数
  pageNum: {
    type: Number,
    default: 1,
  },
  // 每页条数
  pageSize: {
    type: Number,
    default: 5,
  },
  // 是否开启树形结构
  OpenTree: {
    type: Boolean,
    default: false,
  },
  treeNodeNum: {
    type: Number,
    default: 0,
  },
  CustomId: {
    type: String,
    default: "A",
  },
  treeConfig: {
    type: Object,
    default: () => ({
      transform: true,
      rowField: "menuId",
      parentField: "parentId",
      // 用于标识一个字段来赋予子节点参数
      // childrenField:"children"
      expandAll: false
    })
  },
  defaultSort: {
    type: Object,
    default: () => ({
      field: '',
      order: 'desc',
    })
  }
})
const $emit = defineEmits(['checkbox-all', 'checkbox-change', 'radio-change', 'PageChange', 'update:pageNum', 'update:pageSize']);
const {proxy} = getCurrentInstance();
// 更新页数
const currentPage = computed({
  get() {
    return props.pageNum
  },
  set(val) {
    // 不知道什么原理分页的时候要这样计算属性的写
    $emit('update:pageNum', val)
  }
})
const pageSize = computed({
  get() {
    return props.pageSize
  },
  set(val) {
    // 不知道什么原理分页的时候要这样计算属性的写
    $emit('update:pageSize', val)
  }
})
const {tableData, tableColumn, checkbox, radio, loading, total, seq, CustomId} = toRefs(props);

const tablePage = reactive({
  layout: ['Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump', 'Total'],
  autoHidden: false,
  pageSizes: [1, 2, 6, 10],
  total: total,
  currentPage: currentPage,
  pageSize: pageSize
})
const gridOptions = reactive({
  border: false,
  // height: 300,
  align: "center",
  loading: true,
  rowConfig: {
    useKey: true,
  },
  columnConfig: {
    resizable: true
  },


  data: [],
  //右键菜单
  menuConfig: {
    header: {
      options: [
        [
          {code: "FIXED_LEFT_COLUMN", name: "固定到左侧"},
          {code: "FIXED_LEFT_COLUMN_ALL", name: "固定左侧所有列"},
          {code: "FIXED_RIGHT_COLUMN", name: "固定到右侧"},
          {code: "FIXED_RIGHT_COLUMN_ALL", name: "固定右侧所有列"},
          {code: "CLEAR_FIXED_COLUMN", name: "取消固定"},
          {code: "CLEAR_FIXED_COLUMN_ALL", name: "取消全部固定"},
          {code: "FIND_DATA", name: "定位"},
          {code: "FIND_DW", name: "取消排序"},
        ],
      ],
    },
    body: {
      options: [
        [{code: "COPY", name: "复制"}],
        [{code: "DW", name: "定位"}],
      ],
    },

  },
})
// 公共参数查循和存储对应的个性化样式参数
const SearchStyle = reactive({
  userId: useUserStore().$state.id,
  tableId: CustomId.value,
})
const clickCount = ref(0)
// 复选框range的时候实现的参数
const RangeEndList = ref([])
//单元格实现shift操作
const slicedData = ref([])
// 储存开始索引
const startNum = ref()
// 储存结束索引
const endNum = ref()
// 接口获取的个性化样式参数
const tableColumnStyle = ref()

watchEffect(() => {
  initTable()
  sortConfig()
})

onMounted(() => {
  // 因为有异步方法必须先调接口再调判断
  getsaveTableColumn(SearchStyle).then((res)=>{
    if(res.data.tableColumn){
      console.log(JSON.parse(res.data.tableColumn),'res.data.tableColumn')
      tableColumnStyle.value=JSON.parse(res.data.tableColumn)
      init()
    }else{
      init()
    }

  })
})


function init() {
  initTable()
  initColumns()
  // 开启树结构就是树了
  if (props.OpenTree) {
    console.log(props.OpenTree, 'props.IstreeConfig')
    treeConfig()
  }
  // 如果开启默认排序参数就执行默认排序参数的值
  if (props.defaultSort.field) {
    sortConfig()
  }
}

// 加载处理表格数据
function initTable() {
  gridOptions.loading = loading.value
  gridOptions.data = tableData.value
}

//处理加载的配置数据
function initColumns() {
  gridOptions.id = CustomId.value
  gridOptions.columns = []

// 1，如果接口返回了数据就拿接口返回的数据作为个性化样式，因为存的时候设置的复选框什么的都有了，所以不需要重新设置
// 2，否则拿自己设置的本地样式
  if (tableColumnStyle.value) {
    gridOptions.columns = tableColumnStyle.value.map((item) => {
      if (item.slot) {
        let slots = {}
        slots.default = getSolt(item)
        item.slots = slots
      }
      return {
        ...item,
        useKey: item.field,
      };
    })

  }
  else {
    gridOptions.columns = tableColumn.value.map((item) => {
      if (item.slot) {
        let slots = {}
        slots.default = getSolt(item)
        item.slots = slots
      }
      return {
        ...item,
        useKey: item.field,
      };
    })
    // 1，如果（单选，复选）都存在默认单选，否则各选各的
    if (radio.value && checkbox.value) {
      gridOptions.columns.unshift({type: 'radio', width: 60, fixed: 'left'})
    } else if (radio.value) {
      gridOptions.columns.unshift({type: 'radio', width: 60, fixed: 'left'})
    } else if (checkbox.value) {
      // 复选框配置
      gridOptions.checkboxConfig = {
        highlight: true,
        isShiftKey: true,
        range: true,
      }

      gridOptions.columns.unshift({type: 'checkbox', width: 60, fixed: 'left'})
    }
    if (seq.value) {
      gridOptions.columns.unshift({title: '序号', type: 'seq', width: 50, fixed: 'left'})
    }

  }


}

// 树节点
function treeConfig() {
  // 默认给第一列作为展示的下拉图标节点
  if (props.treeNodeNum < gridOptions.columns.length) {
    gridOptions.columns[props.treeNodeNum].treeNode = true
  } else {
    console.log(gridOptions.columns, 'treeNodegridOptions.columns')
    gridOptions.columns[0].treeNode = true
    proxy.$modal.msgWarning(`树节点标识${props.treeNodeNum}大于列表长度${gridOptions.columns.length}`)
  }

  gridOptions.treeConfig = props.treeConfig
}

function sortConfig() {
  gridOptions.sortConfig = {
    defaultSort: props.defaultSort,
    trigger: "cell",
    multiple: true,
    chronological: true
  }
}

function menuClick({menu, row, column}) {
  switch (menu.code) {
    case "DW":
      dw(row, column);
      break;
    case "COPY":
      copyData(row, column);
      break;
    case "FIXED_LEFT_COLUMN":
      fixedLeftColumn(column);
      break;
    case "FIXED_LEFT_COLUMN_ALL":
      fixedLeftColumn(column, "all");
      break;
    case "FIXED_RIGHT_COLUMN":
      fixedRightColumn(column);
      break;
    case "FIXED_RIGHT_COLUMN_ALL":
      fixedRightColumn(column, "all");
      break;
    case "CLEAR_FIXED_COLUMN":
      clearFixedColumn(column);
      break;
    case "CLEAR_FIXED_COLUMN_ALL":
      clearFixedColumn(column, "all");
      break;
    case "FIND_DATA":
      findData(column);
      break;
    case "FIND_DW":
      proxy.$refs["xGrid2"].clearSort();
      this.sort = {};
      this.sortIndex = 0;
      break;
    default:
      // VXETable.modal.message(`点击了 ${menu.name} 选项`);
  }
};

// 复制
function copyData(row, column) {
  if (row && column) {
    if (XEClipboard.copy(row[column.property])) {
      // VXETable.modal.message({
      //   content: "已复制到剪贴板！",
      //   status: "success",
      // });
    }
  }
};

//固定到左侧
function fixedLeftColumn(column, type = "") {
  const $table = proxy.$refs["xGrid2"];
  let t = gridOptions.columns.findIndex((it) => {
    if (!column.field) {
      return it.type === column.type;
    } else {
      return it.field === column.field;
    }
  });
  if (type === "all") {
    for (let i = 0; i <= t; i++) {
      gridOptions.columns[i].fixed = "left";
    }
  } else {
    gridOptions.columns[t].fixed = "left";
  }
  $table.reloadColumn(gridOptions.columns);
  localStoragTableColumn()
}

//固定到右侧
function fixedRightColumn(column, type = "") {
  const $table = proxy.$refs["xGrid2"];
  let t = gridOptions.columns.findIndex((it) => {
    if (!column.field) {
      return it.type === column.type;
    } else {
      return it.field === column.field;
    }
  });
  if (type === "all") {
    for (let i = gridOptions.columns.length - 1; i >= t; i--) {
      gridOptions.columns[i].fixed = "right";
    }
  } else {
    gridOptions.columns[t].fixed = "right";
  }
  $table.loadColumn(gridOptions.columns);
  localStoragTableColumn()
}

//清除固定
function clearFixedColumn(column, type = "") {
  const $table = proxy.$refs["xGrid2"];
  if (type === "all") {
    gridOptions.columns.forEach((it) => {
      it.fixed = "";
    });
  } else {
    let t = gridOptions.columns.findIndex((it) => {
      if (!column.field) {
        return it.type === column.type;
      } else {
        return it.field === column.field;
      }
    });
    gridOptions.columns[t].fixed = "";
  }
  $table.loadColumn(gridOptions.columns);
  localStoragTableColumn()
}

//定位
function findData(column) {
  const $table = proxy.$refs["xGrid2"];
  this.$prompt("请输入关键字", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
  })
      .then(({value}) => {
        let values = value.toString();
        $table.clearCheckboxRow();
        let arr = gridOptions.data.filter((it) => {
          if (it[column.field]) {
            it[column.field] = it[column.field].toString();
            return (
                it[column.field].includes(values) || it[column.field] === values
            );
          }
          // }
          // if (typeof it[column.field] == "number") {
          //   return it[column.field] == value;
          // } else {
          // }
        });
        if (arr.length > 0) {
          // arr.forEach(it=>{
          //   $table.setCurrentRow(it)
          // })
          $table.setCheckboxRow(arr, true);
          $table.scrollToRow(arr[0]);
        } else {
          this.$confirm("未找到数据,请重新查找", "确认信息", {
            confirmButtonText: "是",
            cancelButtonText: "否",
            type: "warning",
          }).then(() => {
            findData(column);
          });
        }
      })
      .catch(() => {
      });
}

//定位
function dw(row, column) {
  // field = column.field;
  // this.name = row[column.property];
  dingwei(column.field, row[column.property]);
  // this.dingwei(row, column);
};

function dingwei(field, name) {
  try {
    const type = VXETable.modal.confirm(
        "搜索字段：" + name + "搜索列：" + field
    );
  } catch (error) {

  }

}

// 复选框选中改变事件
function handleCheckboxChange(val) {
  console.log(val, 'val复选')
  $emit('checkbox-change', val.records)
}

//复选框参数配置
function checkboxConfig() {

}

// 复选框选中全部事件
function handleCheckboxAll(val) {
  $emit('checkbox-all', val.records)
}

// 单选框选中改变事件
function handleRadioChange(val) {
  $emit('radio-change', val.records)
}

// 分页事件改变
function handlePageChange({currentPage, pageSize}) {
  // console.log(currentPage, pageSize, 'currentPage, pageSize')
  // 可以将参数实时渲染会原来的组件
  $emit('PageChange', {pageNum: currentPage, pageSize: pageSize})

}

// 插槽用来添加是否有solt
function getSolt(val) {
  //将值作为参数拼接一下，不然不识别
  return val.field + "_default";
}

// 单击单元格事件触发的函数，同时如果触发了“快捷键（shift）”事件判断
function handleCellClick({row, rowIndex, $event}) {
  // 1，按住shift的判断
  if ($event.shiftKey) {
    //,2.1点击次数判断累加，用来判断奇数次还是偶数次点击
    clickCount.value++;
    // 2.2奇数次点击的判断
    if (clickCount.value % 2 === 1) {
      将索引
      startNum.value = rowIndex
      const index = slicedData.value.indexOf(rowIndex);
      if (index !== -1) {
        slicedData.value.splice(index, 1);
      } else {
        slicedData.value.push(rowIndex)
      }
    } else {
      // 2.3偶数次的点击判断
      // 2.3.1偶数次将索引给结束索引
      endNum.value = rowIndex
      // 2.3.2循环将对应的开始到结束区间内的索引遍历出来，赋给数组，储存
      for (let i = startNum.value + 1; i <= endNum.value; i++) {
        // 2.3.3判断是否已经存在这个数字
        const index = slicedData.value.indexOf(i);
        // 2.3.4存在的话将数组中的这个参数删除掉，避免根据这个参数拿到table的数据
        if (index !== -1) {
          slicedData.value.splice(index, 1);
        } else {
          // 2.3.5否则就是新的参数，把参数填充累加到数组中，用于回显复选框
          slicedData.value.push(i)
        }
      }
      // 将对应的复选框清理和回显
      isCheckBox()
    }

  }

}

function isCheckBox() {
  const $table = proxy.$refs["xGrid2"];
  $table.clearCheckboxRow()
  slicedData.value.forEach((item) => {
    console.log(tableData.value[item], 'item')
    $table.setCheckboxRow(tableData.value[item], true)
  })
}


function checkboxRangeChange({records, $event}) {
  if ($event.shiftKey) {

  }
}


// 根据复选的滑动shift实现间隔筛选
function checkboxRangeEnd({records, $event}) {
  if ($event.shiftKey) {
    records.forEach((item) => {
      if (RangeEndList.value.length > 0) {
        const data = RangeEndList.value.some(it => JSON.stringify(it) === JSON.stringify(item))
        if (!data) {
          RangeEndList.value.push(item)
        } else {
          const index = RangeEndList.value.findIndex(it => it === item);
          if (index !== -1) {
            RangeEndList.value.splice(index, 1);
          }
        }
      } else {
        RangeEndList.value.push(item)
      }
    })
    const $table = proxy.$refs["xGrid2"];
    $table.clearCheckboxRow()
    RangeEndList.value.forEach((item) => {
      $table.setCheckboxRow(item, true)
    })
  }

}

function customCheckMethod({row, rowIndex}) {
  console.log(rowIndex, 'rowIndex')
}

function customClick() {
  console.log('hahahahah')
}

function resizableChange() {
  localStoragTableColumn()
}

// 缓存对应的个性化参数
function localStoragTableColumn() {
  const $table = proxy.$refs["xGrid2"];
  const tableColumn = $table.getTableColumn().tableColumn.filter((item) => {
    item.width = item.renderWidth
    return item;
  })
  console.log($table.getTableColumn(),'$table.getTableColumn()')
  console.log(tableColumn,'tableColumn')
  SearchStyle.tableColumn = JSON.stringify(tableColumn)

  // 调用储存个性化样式
  // getsaveTableColumn(SearchStyle)

}
</script>

<template>
  <vxe-grid
      v-bind="gridOptions"
      @checkbox-change="handleCheckboxChange"
      @radio-change="handleRadioChange"
      @checkbox-all="handleCheckboxAll"
      ref="xGrid2"
      @menu-click="menuClick"
      @checkbox-range-change="checkboxRangeChange"
      @checkbox-range-end="checkboxRangeEnd"
      @cell-click="handleCellClick"
      @custom="customClick"
      @resizable-change="resizableChange"
  >
    <!--    @checkbox-range-change="checkboxRangeChange"-->
    <!--       @checkbox-range-start="checkboxRangeStart"-->
    <!--    @checkbox-range-end="checkboxRangeEnd"-->
    <!--      @cell-click="handleCellClick"-->
    <template v-for="(item,index) in props.tableColumn" :key="index" #[getSolt(item)]="{ row }">
      <!--具名插槽-->
      <slot :name="item.field" :row="row"></slot>
    </template>
    <template v-if="isPage" #pager>
      <vxe-pager
          :layouts="tablePage.layout"
          v-model:current-page="tablePage.currentPage"
          v-model:page-size="tablePage.pageSize"
          :total="tablePage.total"
          :page-sizes="tablePage.pageSizes"
          :auto-hidden="tablePage.autoHidden"
          :tree-config="gridOptions.treeConfig"

          @page-change="handlePageChange">
      </vxe-pager>
    </template>
  </vxe-grid>
  <!--  <pagination-->
  <!--      v-show="total > 0"-->
  <!--      :total="total"-->
  <!--      v-model:page="queryParams.pageNum"-->
  <!--      v-model:limit="queryParams.pageSize"-->
  <!--      @pagination="getList"-->
  <!--  />-->
</template>

<style scoped lang="scss">

</style>
